package com.pds.web.operationLog.aspect;

import com.pds.common.core.domain.entity.SysUser;
import com.pds.common.utils.SecurityUtils;
import com.pds.common.utils.ServletUtils;
import com.pds.common.utils.ip.IpUtils;
import com.pds.web.operationLog.annotation.OprLog;
import com.pds.web.operationLog.entity.PdsOperationLog;
import com.pds.web.operationLog.service.PdsOperationLogService;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author srf
 * @date 2024/2/7
 * @version 1.0
 * @description: 操作日志切面处理类
 */
@Slf4j
@Aspect
@Component
public class OperationLogAspect {
    @Resource
    private PdsOperationLogService pdsOperationLogService;

    /**
     * 设置操作日志切入点   在注解的位置切入代码
     */
    @Pointcut("@annotation(com.pds.web.operationLog.annotation.OprLog)")
    public void oprLogPointCut() {
    }

    /**
     * 记录操作日志
     * @param joinPoint 方法的执行点
     * @param result  方法返回值
     */

    @AfterReturning(returning  = "result", value = "oprLogPointCut()")
    public void saveOperLog(JoinPoint joinPoint, Object result){
        try{
            // 获得注解
            OprLog controllerLog = getAnnotationLog(joinPoint);
            if (controllerLog == null)
            {
                return;
            }
            //将返回值转换成map集合
            //Map<String, String> map = (Map<String, String>) result;
            // 返回值信息(根据需求决定是否记录)
            //String msg = MapUtils.getString(map, "msg");
            UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            // 获取Ip地址
            String ipAddress = IpUtils.getIpAddr();
            PdsOperationLog operationLog = new PdsOperationLog();
            // 获取用户信息(0L代表没有登陆系统用户)
            SysUser user = SecurityUtils.getLoginUser().getUser();
            if(!Objects.isNull(user)){
                operationLog.setUserId(user.getUserId());
                operationLog.setUserName(user.getNickName());
            }else{
                operationLog.setUserId(0L);
            }
            operationLog.setUserAgent(browser);
            operationLog.setOperationIp(ipAddress);
            operationLog.setOperationContent(controllerLog.content());
            pdsOperationLogService.insert(operationLog);
        }catch (Exception e){
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", e.getMessage());
        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private OprLog getAnnotationLog(JoinPoint joinPoint)
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null)
        {
            return method.getAnnotation(OprLog.class);
        }
        return null;
    }
}
